#include "ringqueue.hpp"
#include"Task.hpp"
#include <iostream>
#include <string>

using namespace std;

struct ThreadData
{
    //Ringqueue<int> *rq;
    Ringqueue<Task> *rq;
    std::string name;
};

void *Produce(void *args)
{
    ThreadData *tmp = static_cast<ThreadData *>(args);
    while (true)
    {
        //int data = rand() % 99 + 1;
        Task t(rand()%10+1,rand()%10,oper[rand()%5]);
        tmp->rq->push(t);
        cout <<"producer "<<tmp->name<< "  produced a data :" << t.display() << endl;
    }
}

void *consumption(void *args)
{
    ThreadData *tmp = static_cast<ThreadData *>(args);
    while (true)
    {
        Task receive;
        tmp->rq->pop(&receive);
        receive.run();
        cout <<"consumer "<< tmp->name<<" has consumed a data :" << receive.result() << endl;
        sleep(1);
    }
}

int main()
{
    srand(time(nullptr) ^ getpid());
    //Ringqueue<int> *rq = new Ringqueue<int>();
    Ringqueue<Task> *rq = new Ringqueue<Task>();

    pthread_t p[5], c[3];

    for (int i = 0; i < 5; i++)
    {
        ThreadData *td = new ThreadData();
        td->rq = rq;
        td->name = "Thread-" + to_string(i);

        pthread_create(p + i, nullptr, Produce, td);
    }

    for (int i = 0; i < 3; i++)
    {
        ThreadData *td = new ThreadData();
        td->rq = rq;
        td->name = "Thread-" + to_string(i);

        pthread_create(p + i, nullptr, consumption, td);
    }

    for (int i = 0; i < 5; i++)
    {
        pthread_join(p[i], nullptr);
    }

    for (int i = 0; i < 3; i++)
    {
        pthread_join(c[i], nullptr);
    }

    return 0;
}
